Hallo zusammen und willkommen zu unserem heutigen Abschnitt über ein grundlegendes und wichtiges Thema im Datenbankdesign, die Normalisierung und die verschiedenen Normalformen. Wir sprechen hier speziell über relationale Datenbanksysteme. Ziel dieser Einheit ist es, Ihnen ein klares Verständnis davon zu vermitteln, warum Normalisierung notwendig ist und wie man sie sinnvoll umsetzt. Was steckt hinter dem Begriff Normalisierung? Ganz einfach, wir meinen damit die gezielte Aufteilung von Attributen, also Tabellenspalten, in mehrere logisch getrennte Tabellen, sogenannte Relationen. Das Ganze passiert nicht willkürlich, sondern folgt bestimmten Normalisierungsregeln. Das übergeordnete Ziel ist, eine Struktur zu schaffen, die keine vermeidbaren Redundanzen mehr enthält. Also, keine doppelten Informationen, die bei Änderungen inkonsistent werden könnten. Und warum ist das so wichtig? Stellen Sie sich vor, ein Kunde ist in mehreren Datensätzen mit seiner Adresse gespeichert. Ändert sich diese, müssten wir alle Vorkommen manuell anpassen. Passiert das nicht vollständig, entstehen sogenannte Datenbank-Anomalien, also veraltete oder widersprüchliche Informationen. Zudem belegt doppelte Speicherung unnötig Speicherplatz. All das vermeidet man durch sinnvolle Normalisierung. Schauen wir uns als Ausgangspunkt die Nullte Normalform an. Sie beschreibt den Zustand, in dem alle Daten noch unnormalisiert in einer einzigen Tabelle liegen. Typischerweise begegnet uns dieser Zustand zu Beginn eines Projekts, etwa bei der Anforderungsanalyse. Es gibt noch keine Struktur, alle Daten sind gesammelt, aber nicht getrennt, das ist der Ausgangspunkt für jede Normalisierung. Die Definition der Nullten Normalform lautet, Eine Tabelle befindet sich in dieser Form, wenn alle Datenelemente der realen Welt in einer einzigen Tabelle gesammelt sind, ohne jegliche Struktur. Ein klassisches Beispiel ist eine Tabelle mit Rechnungsnummer, Datum, Kundennamen, Adresse, gekauften Produkten, deren Mengen und Preisen, Lieferantendaten, alles in einer Zeile, wie wir es auch auf der nächsten Folie sehen können. Hier beginnt unser Normalisierungsprozess. In dieser Tabelle sehen wir ein klassisches Beispiel für eine unnormalisierte Tabelle, wie sie typischerweise in der Nullten Normalform vorliegt, also ganz am Anfang des Normalisierungsprozesses. Diese Tabelle enthält Daten aus mehreren Themenbereichen, die nicht getrennt wurden, sondern alle in einer einzigen, großen Struktur zusammengefasst sind. Auf den ersten Blick wirkt sie vielleicht praktisch, alles steht an einem Ort, Rechnungsnummern, Kundendaten, Produktinformationen, Lieferantendaten. Aber genau das ist das Problem. Daten sind zum Teil doppelt gespeichert und nicht atomar. Zum Beispiel sehen sie, dass die Kundendaten von Julia Meier mehrfach erscheinen. Sollte wir nun zum Beispiel die Adresse ändern müssen, müssen wir dies an mehreren Stellen tun was wieder zu Fehlern führen kann. Der erste Schritt in Richtung Struktur ist die Erste Normalform. Eine Tabelle erfüllt diese, wenn alle Datenfelder atomar sind. Das bedeutet, Jeder Wert steht einzeln in einem Datenfeld. Keine Listen in einer Zelle, keine zusammengesetzten Adressfelder. Stattdessen bekommt jede Information ihre eigene Spalte, Straße, Hausnummer, Postleitzahl, Ort, jeweils separat. Auf dieser Folie sehen wir den Übergang von der Nullten zur Ersten Normalform. Alle rot markierten Zeilen zeigen Felder, die sich noch nicht an das Prinzip der Ersten Normalform halten.In der Namenszeile zum Beispiel sind Vorname und Nachname gemeinsam gespeichert, also in einem einzigen Feld. Das widerspricht dem Prinzip der Atomarität, das verlangt, dass jede Information in einem eigenen Datenfeld steht. Das selbe Problem haben wir auch in den Zeilen für die Kundenanschrift, Gültig bis und Lieferantenanschrift. Alle diese Beispiele zeigen, die Daten sind zwar inhaltlich korrekt, aber nicht sauber strukturiert. Und genau hier greift die Erste Normalform, sie zwingt uns dazu, die Daten so zu organisieren, dass jede Spalte nur genau eine Informationseinheit enthält. Auf der nächsten Folie trennen wir diese Zeilen dann intern auf. Nun sehen wir das Ergebnis der Ersten Normalform, also die erste große strukturelle Verbesserung unserer Daten. Alle Felder, die zuvor rot markiert waren, wurden jetzt atomar aufgeteilt, so wie es die Erste Normalform verlangt. Die Zeile für den Namen wurde beispielsweise in Vorname und Nachname getrennt. Damit ist die Information jetzt klarer strukturiert und getrennt erfassbar, ideal für Abfragen der Sortierungen. Auch bei der Kundenanschrift erkennen wir die Veränderung deutlich, was vorher als eine lange Zeichenkette vorlag, wurde jetzt aufgeteilt in Straße, Hausnummer, Postleitzahl und Ort, jeweils in einem eigenen Datenfeld. So lässt sich jede einzelne dieser Informationen gezielt verwenden, etwa bei der Filterung nach Städten oder Postleitzahlen. Das selbe ist natürlich auf für die Zeilen Gültig bis und Lieferantenanschrift. All diese Anpassungen sorgen dafür, dass die Tabelle nun den Anforderungen der Ersten Normalform entspricht, jede Spalte enthält genau eine einzelne, unteilbare Informationseinheit. Damit ist eine wichtige Grundlage für die nächsten Normalisierungsstufen geschaffen. Auf der Ersten baut die Zweite Normalform auf. Sie verlangt, dass jedes Nicht-Schlüsselattribut vollständig vom gesamten Primärschlüssel abhängt. Wenn der Primärschlüssel beispielsweise aus zwei Spalten besteht, dürfen die restlichen Spalten nicht nur von einer dieser beiden Spalten abhängig sein, das wäre eine partielle Abhängigkeit und widerspricht der Zweiten Normalform. Um eine Tabelle in die Zweite Normalform zu bringen, identifiziert man zunächst den Primärschlüssel, dieser kann auch aus mehreren Attributen bestehen. Wichtig ist dann, dass alle anderen Attribute vollständig vom gesamten Primärschlüssel abhängen. Sobald ein Attribut nur von einem Teil des Schlüssels abhängig ist, spricht man von einer partiellen Abhängigkeit. In diesem Fall muss die Tabelle weiter zerlegt werden, damit jede Information genau dort liegt, wo sie logisch hingehört. So vermeidet man Redundanzen und sorgt für eine saubere Datenstruktur. In dieser Tabelle haben wir die Primärschlüssel farblich hervorgehoben. Diese markieren die logischen Trennlinien zwischen verschiedenen Datengruppen, wie etwa Rechnungen, Kunden, Produkte oder Lieferanten. Ziel ist es, auf Basis dieser Schlüssel zu erkennen, welche Attribute zu welcher Datenentität gehören und ob sie korrekt zugeordnet sind. In dieser Folie geht es um die Rechnungen selbst. Die Rechnungsnummer ist der Primärschlüssel dieser Tabelle. Alle weiteren Attribute, wie das Rechnungsdatum, die Zahlungsart und die verknüpfte Kundennummer, hängen ausschließlich von dieser Rechnungsnummer ab. Weiterhin haben wir die Kundendaten in eine eigene Datengruppe ausgelagert. Die Kundennummer ist hier klar als Primärschlüssel markiert, sie identifiziert jeden Kunden eindeutig. Alle weiteren Attribute, wie der Kundentyp, Vorname und Nachname, ein möglicher Firmenname sowie die Kundenanschrift mit Straße, Hausnummer, Postleitzahl und Ort, hängen ausschließlich von dieser Kundennummer ab. Hier sehen wir gleich zwei Datengruppen. Zunächst die Kreditkartendaten, bei denen die Kreditkartennummer als Primärschlüssel dient. Sie ist eindeutig und identifiziert eine Kreditkarte und ist somit auch eindeutig einem Kunden zugeordnet. Verknüpft ist sie mit einer Kundennummer und einem Gültigkeitsdatum, bestehend aus Monat und Jahr. Zusätzlich folgt die Produkt-Tabelle. Auch hier ist der Primärschlüssel klar markiert, die Produktnummer. Diese identifiziert jedes Produkt eindeutig. Zu jedem Produkt sind dann nur noch die Informationen gespeichert, die ausschließlich davon abhängen, also der Produktname und der Einzelpreis. Zum Schluss haben wir noch die Lieferantendaten. Der Primärschlüssel ist hier die Lieferanten-ID. Weitere Informationen wie Lieferantenname und die Lieferantenanschrift sind direkt von dieser ID abhängig. Die Anschrift selbst ist wieder sauber zerlegt in Straße, Hausnummer, Postleitzahl und Ort. Damit ist auch diese Tabelle vollständig 2NF-konform. Aus unserer ursprünglichen Tabelle bleiben somit nur noch die Menge und der Rabatt übrig. Bei genauerer Betrachtung wird klar, diese Informationen gehören nicht direkt zur Rechnung, sondern zu einzelnen Rechnungspositionen. Eine Rechnung besteht aus mehreren Positionen, und jede Position enthält ein bestimmtes Produkt in einer bestimmten Menge. Genau hier wird die Menge gespeichert. Ein Rabatt kann ein Lieferant geben auf einzelne Produkte ab einer gewissen Menge! Ein Lieferant kann mehrere Produkte liefern und ein Produkt kann von mehreren Lieferanten geliefert werden! Also wird der Rabatt zwischen den Produkten und deren Lieferanten eingeordnet. Hier sehen wir, wie Menge und Rabatt nun korrekt in zwei separate Tabellen überführt wurden, jeweils passend zur Zweiten Normalform. Die Rechnungsposition verwendet als Schlüssel die Kombination aus Rechnungsnummer und einer laufenden Nummer oder Produktnummer. Die Menge ist eindeutig dieser Kombination zugeordnet, sie hängt also vom gesamten Schlüssel ab und erfüllt damit die Anforderungen der Zweiten Normalform. In der Tabelle Produkt-Rabatt bestehen die Schlüssel aus Produktnummer und Lieferanten-ID. Nur wenn beide Werte gemeinsam betrachtet werden, ergibt sich eine eindeutige Rabattregel. Auch hier gilt, sowohl Menge als auch der Rabatt selbst sind vom gesamten Schlüssel abhängig. Die Dritte Normalform baut auf der Zweiten auf und fordert zusätzlich, dass kein Nicht-Schlüsselattribut transitiv von einem anderen abhängen darf. Alle Werte sollen also direkt vom Primärschlüssel abhängen, nicht über Umwege. Damit verhindert man effektiv Redundanzen und Anomalien, ohne die Performance für Abfragen zu verlieren. In der Praxis ist die Dritte Normalform meist völlig ausreichend, um eine gute Balance aus Datenqualität und Effizienz zu erreichen. Weitere Normalformen wie die Vierte oder Fünfte existieren zwar, spielen aber im Alltag kaum eine Rolle. Hier sehen wir eine typische Verletzung der Dritten Normalform. Wir haben eine Kundentabelle, in der sowohl Vorname und Nachname als auch ein Firmenname vorkommen. Ob ein Name oder ein Firmenname eingetragen wird, hängt aber nicht direkt vom Primärschlüssel, also der Kundennummer, ab, sondern vom Kundentyp. Das heißt, der Kundentyp entscheidet, welches Attribut überhaupt relevant ist. Diese indirekte Abhängigkeit nennt man eine transitive Abhängigkeit, und genau die widerspricht der Dritten Normalform. Die Lösung besteht darin, diese Abhängigkeit aufzulösen. Wir behalten die allgemeine Tabelle Kunde mit Kundennummer und Adresse, und führen zwei spezialisierte Tabellen ein, Privatkunde und Geschäftskunde. In der Tabelle Privatkunde speichern wir Vorname und Nachname, in der Tabelle Geschäftskunde den Firmennamen, jeweils über die Kundennummer verbunden. So ist sichergestellt, dass jedes Attribut direkt vom jeweiligen Primärschlüssel abhängt und keine transitiven Abhängigkeiten mehr bestehen. Werfen wir auch noch einen Blick auf die Adressdaten. Was sofort auffällt, sowohl bei Kunden als auch bei Lieferanten finden wir dieselben Felder, Straße, Hausnummer, Postleitzahl und Ort. Diese Informationen sind nicht direkt vom Primärschlüssel der jeweiligen Tabelle abhängig, sondern bilden ein eigenes Datenobjekt. Noch dazu tauchen sie mehrfach auf, was zu Redundanz führt und damit auch zu einer Verletzung der Dritten Normalform. Deshalb ist es sinnvoll eine zentrale Adresstabelle einzuführen. Kunde und Lieferant verweisen jetzt nur noch auf eine Adress-ID, die mit ihrer tatsächlichen Adresse in der neuen Tabelle verknüpft ist. Damit speichern wir jede Adresse nur noch einmal und vermeiden doppelte Daten. Gleichzeitig stellen wir sicher, dass alle Informationen direkt vom Primärschlüssel abhängen, so wie es die Dritte Normalform verlangt. In dieser Folie geht die Optimierung noch einen Schritt weiter. Bei genauer Betrachtung erkennt man: Postleitzahl und Ort stehen in einer festen Beziehung zueinander, das ist ebenfalls eine Abhängigkeit. Deshalb wäre es sogar möglich, in der Adresstabelle nur noch die Postleitzahl zu speichern und den dazugehörigen Ort über eine separate PLZ-Ort-Tabelle zu verwalten. Diese Feinoptimierung geht zwar über die klassische Dritte Normalform hinaus, kann aber bei sehr großen Datenmengen sinnvoll sein. Die Normalisierung sorgt für weniger Redundanz, verhindert Anomalien und schafft klare, wartbare Strukturen. Dadurch entstehen jedoch mehr Tabellen, die über Primär- und Fremdschlüssel verbunden sind – was Abfragen komplexer macht. Die Dritte Normalform bietet dabei einen guten Kompromiss, sie gewährleistet Konsistenz und Effizienz, ohne die Performance unnötig zu belasten, und ist in der Praxis für die meisten Anwendungen vollkommen ausreichend.